// EG4DetectorConstruction.cc -- the implementation of the class
// Created: Jan. 23, 2019, transcribed by Asia SUN, asia.rabbit@163.com
// Last modified: Jan. 23, 2019 by Asia SUN

#ifndef EG4MagneticField_h
#define EG4MagneticField_h

#include "G4MagneticField.hh"

class G4GenericMessenger;

class EG4MagneticField : public G4MagneticField{
public:
  EG4MagneticField();
  virtual ~EG4MagneticField();

  virtual void GetFieldValue(const double point[4], double *bField) const;

  void SetField(double val){ fBy = val; }
  double GetField() const{ return fBy; }
  
  void SetIsUniformMagneticField(bool opt){
    fIsUniformMagneticField = opt;
    if(!fIsUniformMagneticField) LoadMagneticFieldFile();
  }
  bool IsUniformMagneticField(){ return fIsUniformMagneticField; }

  // magnetic field boundaries for uniform magnetic field mode
  static const double kzMagIn, kzMagOut;

protected:
  virtual void DefineCommands();
  // read the magnetic field measurement file
  // generated from measurements using Hall sensor
  void LoadMagneticFieldFile(const G4String &file = "../g4/config/magnetic.txt");
  // assign B with the magnetic intensity vector at position p
  // return false if particle hit the iron wall of the dipo
  bool GetMagneticIntensity(const double p[4], double*B) const;

  G4GenericMessenger *fMessenger;
  bool fIsUniformMagneticField; // whether use uniform or real magnetic field

  // the magnetic field
  // this is the one eighth of the whole magnetic field for the dipole magnet.
  // x: -1000, 0; y: 0, 90; z: 0, 1050         10mm spacing
  double fBy; // the B for uniform or Bmax for real mag
  double fB[3][101][10][106]; // [BxByBz][x][y][z]
  bool fIsFileLoaded; // to mark if the magnetic field file is loaded
};

#endif
